﻿using System;
using System.Collections.Generic;

namespace Remoting.Reactive
{
    internal class RemotablePool : IRemotablePool
    {
        private readonly Dictionary<string, IRemotable> _remotables;
        private bool _disposed;

        public RemotablePool()
        {
            _remotables = new Dictionary<string, IRemotable>();
        }

        public void Dispose()
        {
            if (!_disposed)
            {
                lock (_remotables)
                {
                    foreach (var remotable in _remotables.Values)
                    {
                        var disposable = remotable as IDisposable;
                        if (disposable != null)
                        {
                            try
                            {
                                disposable.Dispose();
                            }
// ReSharper disable EmptyGeneralCatchClause
                            catch
// ReSharper restore EmptyGeneralCatchClause
                            {}
                        }
                    }
                    _remotables.Clear();
                }
                _disposed = true;
            }
        }

        public void Add(IRemotable remotable)
        {
            Guard.Requires<ArgumentNullException>(remotable != null);
            lock (_remotables)
            {
                _remotables.Add(remotable.Id, remotable);
            }
        }

        public IRemotable Get(string remotableId)
        {
            Guard.Requires<ArgumentException>(!string.IsNullOrEmpty(remotableId));
            lock (_remotables)
            {
                IRemotable remotable;
                _remotables.TryGetValue(remotableId, out remotable);
                return remotable;
            }
        }

        public IRemotable Take(string remotableId)
        {
            Guard.Requires<ArgumentException>(!string.IsNullOrEmpty(remotableId));
            lock (_remotables)
            {
                IRemotable remotable;
                if (_remotables.TryGetValue(remotableId, out remotable))
                {
                    _remotables.Remove(remotableId);
                }
                return remotable;
            }
        }
    }
}
